using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Boa.AIT.AccesoDatos.Entidades;
using Boa.AIT.AccesoDatos.Contratos;
using Boa.AIT.Negocios.Servicios;
using Boa.AIT.Negocios.Excepciones;

namespace Boa.AIT.Negocios
{
   /// <summary>
   /// Implementacion de la interface IAIT_AsignaEmpleadoNegociosServicio, los metodos que estan definidos en el contrato IAIT_AsignaEmpleadoNegociosServicio serán accesibles desde un contexto externo
   /// </summary>	
   public class AIT_AsignaEmpleadoNegocios : IAIT_AsignaEmpleadoNegociosServicio
   {
	private IAIT_AsignaEmpleadoAccesoDatos accesoDatos;
	public AIT_AsignaEmpleadoNegocios()
	{		
		accesoDatos = DataFactory.Current.GetAIT_AsignaEmpleadoAccesoDatos();
	}
	
	/// <summary>
    /// Devuelve una lista de AIT_AsignaEmpleado's de las ocurrencias encontradas a partir del filtro
    /// </summary>    
	public List<AIT_AsignaEmpleado> BuscarPorFiltro(string filtro)
	{
		return accesoDatos.BuscarPorFiltro(filtro).ToList();
	}    

	#region operaciones básicas
	
	/// <summary>
    /// Elimina la entidad AIT_AsignaEmpleado, lanzará una excepcion si la entidad guarda dependencia a otras entidades
    /// </summary>	
	public void Eliminar(AIT_AsignaEmpleado entidad)
	{
		try
		{
		    accesoDatos.Delete(accesoDatos.GetById(entidad.Id));
	    }
		catch(Exception ex)
		{
		   throw new AIT_AsignaEmpleadoEliminarExcepcion("AIT_AsignaEmpleado");
		}
	}
	
	/// <summary>
    /// Devuelve AIT_AsignaEmpleado, buscada por su Id, si no existe, entonces devuelve null
    /// </summary>	
	public AIT_AsignaEmpleado ObtenerPorId(object Id)
	{
		return accesoDatos.GetById(Id);
	}

	/// <summary>
    /// Devuelve List<AIT_AsignaEmpleado>, de todas la entidades de ese tipo
    /// </summary>	
	public List<AIT_AsignaEmpleado> ObtenerTodas()
	{
		return accesoDatos.GetAll().ToList();
	}

	
	/// <summary>
    /// Guarda AIT_AsignaEmpleado, previa ejecucion satisfactoria de las reglas de negocio
    /// </summary>	
	public AIT_AsignaEmpleado Guardar(AIT_AsignaEmpleado entidad)
	{
		//Agregar aqui las reglas de negocio.......	
		if(entidad==null)
		 throw new AIT_AsignaEmpleadoRequeridoExcepcion(); 
		
		#region Foreign Keys Values
                if(entidad.AsignarEquipoAlmacenId_FK > 0 && entidad.AsignarEquipoAlmacen==null)
                    entidad.AsignarEquipoAlmacen = DataFactory.Current.GetAIT_AsignarEquipoAlmacenAccesoDatos().GetById(entidad.AsignarEquipoAlmacenId_FK);
                #endregion

        if (string.IsNullOrEmpty(entidad.Guid))
            entidad.Guid = System.Guid.NewGuid().ToString();

			
		if (entidad.Id == 0)
			accesoDatos.Insert(entidad);
		else
			accesoDatos.Update(entidad);

		return entidad;
	}

	#endregion


    public AIT_AsignaEmpleado GetPorAsignacionEquipoAlmacen(int AsignaEquipoAlmacenId)
    {
        return accesoDatos.GetPorAsignacionEquipoAlmacen(AsignaEquipoAlmacenId);
    }

    public void AsignarEquipo(int AsignarEquipoAlmacenId, int EmpleadoId)
    {
        //validar si es que el equipo tiene configurado las acciones del mantenimiento preventivo
                
        AIT_AsignarEquipoAlmacen asignacion = DataFactory.Current.GetAIT_AsignarEquipoAlmacenAccesoDatos().GetById(AsignarEquipoAlmacenId);

        string codigosEquipos = DataFactory.Current.GetAIT_EquipoDisponibleAccesoDatos().GetEquiposSinMantenimiento(asignacion.EquipoDisponible.Id);
        if(!string.IsNullOrEmpty(codigosEquipos))
            throw new Exception("Los siguientes equipos no tienen acciones de mantenimiento preventivo, configure antes de continuar : "+codigosEquipos);


        //var equipos =  DataFactory.Current.GetAIT_EquipoITAccesoDatos().ListarEquiposDeEquipoDisponible(asignacion.EquipoDisponible.Id);

        try
        {
            accesoDatos.BeginTransaction();

            AIT_AsignaEmpleado asignaEmpleado = new AIT_AsignaEmpleado();
            asignaEmpleado.EmpleadoId = EmpleadoId;
            asignaEmpleado.EstaActivo = true;
            asignaEmpleado.FechaEntrega = DateTime.Now;
            asignaEmpleado.Guid = System.Guid.NewGuid().ToString();
            asignaEmpleado.Motivo = "Asignacion Directa";
            asignaEmpleado.AsignarEquipoAlmacen = DataFactory.Current.GetAIT_AsignarEquipoAlmacenAccesoDatos().GetById(AsignarEquipoAlmacenId);
            accesoDatos.Insert(asignaEmpleado);
                      

            /********************************GUARDAR TODO EL MANTENIMIENTO POSIBLE PARA UN ANO**********************************************/

            var datas = DataFactory.Current.GetAIT_MantenimientoPreventivoAccesoDatos().GetItemsMantenimiento(asignaEmpleado.Id);
            AIT_AccionesMantenimiento accion = null;
            AIT_EquipoDisponible equipo = null;

            DateTime fecha = DateTime.Now;
            DateTime fechaLimite = fecha.AddDays(365);

            foreach (var item in datas)
            {
                while (fecha <= fechaLimite)
                {
                    fecha = fecha.AddDays(item.FrecuenciaDias);
                    accion = DataFactory.Current.GetAIT_AccionesMantenimientoAccesoDatos().GetById(item.AccionesMantenimientoId);
                    AIT_MantenimientoPreventivo mantenimiento = new AIT_MantenimientoPreventivo()
                        {
                            AccionesMantenimiento = accion,
                            EquipoDisponibleItem = DataFactory.Current.GetAIT_EquipoDisponibleItemAccesoDatos().GetById(item.EquipoDisponibleItemId),
                            AsignaEmpleado = asignaEmpleado,
                            FechaProgramada = fecha,
                            Responsable = "Tecnico",
                            Observaciones = "Programado Automaticamente por el sistema en fecha " + DateTime.Now.ToString(),
                            Descripcion = "Realizar "+accion.Accion+", en fecha "+fecha.AddDays(item.NotificarDiasAntes * -1).ToString(),
                            FechaNotificacion = fecha.AddDays(item.NotificarDiasAntes * -1)
                        };
                    DataFactory.Current.GetAIT_MantenimientoPreventivoAccesoDatos().Insert(mantenimiento);

                }

                fecha = DateTime.Now;               
            }


            accesoDatos.CommitTransaction();
        }
        catch (Exception)
        {
            accesoDatos.RollbackTransaction();
            
        }




        

    }
   }
}


